
#include <windows.h>
#include <codecvt>
#include <psapi.h>
#include "vector"
#include "iostream"
#include "../utils/StringUtils.hpp"
#include "../includes/window_api.h"


/**
 * 获取窗口标题
 * @param hwnd
 * @return
 */
std::string getWindowTitle(HWND hwnd) {
    int length = GetWindowTextLengthW(hwnd) + 1;
    if (length <= 1) return "";
    auto title = new WCHAR[length];
    GetWindowTextW(hwnd, title, length);
    std::string utf8Title = wideStringToUtf8(std::wstring(title, length - 1));
    delete[] title;
    return utf8Title;
}

/**
 * 获取窗口类名
 * @param hwnd
 * @return
 */

std::string getClassName(HWND hwnd) {
    auto className = new WCHAR[MAX_CLASS_NAME];
    int length = GetClassNameW(hwnd, className, MAX_CLASS_NAME);
    std::string utf8ClassName = wideStringToUtf8(std::wstring(className, length));
    delete[] className;
    return utf8ClassName;
}
/**
 * 获取窗口执行文件路径
 * @param hwnd
 * @return
 */
std::string getWindowModuleFileName(HWND hwnd) {
    DWORD processId;
    GetWindowThreadProcessId(hwnd, &processId);
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processId);
    if (hProcess == nullptr) {
        // 处理错误情况，例如返回空字符串或抛出异常
        return "";
    }
    auto fileName = new WCHAR[MAX_PATH];
    UINT length = GetModuleFileNameExW(hProcess, nullptr, fileName, MAX_PATH);
    if (length == 0) {
        // 获取失败，处理错误并关闭句柄
        CloseHandle(hProcess);
        return "";
    }
    CloseHandle(hProcess);

    std::string utf8FileName = wideStringToUtf8(std::wstring(fileName, length));
    delete[] fileName;
    return utf8FileName;
}

BOOL CALLBACK EnumWindowProc(HWND hwnd, LPARAM params) {
    auto *windowHandles = reinterpret_cast<std::vector<Window> *>(params);
    std::string title = getWindowTitle(hwnd);
    std:: string fileName = getWindowModuleFileName(hwnd);
    if (title.length() != 0 && fileName.length() != 0) {
        Window window{};
        window.title = title;
        window.className = getClassName(hwnd);
        window.fileName = fileName;
        window.handler = hwnd;
        windowHandles->push_back(window);
    }

    return TRUE;

}

std::vector<Window> getAllWindows() {
    std::vector<Window> windowHandlers;
    EnumWindows(EnumWindowProc, reinterpret_cast<LPARAM>(&windowHandlers));
    for (const Window &window: windowHandlers) {
        std::cout << window.title << '\t' << window.className << '\t' << window.fileName << std::endl;
    }
    std::cout << windowHandlers.size() << std::endl;
    return windowHandlers;
}

